package com.passion.aspects;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * description 方法耗时切面
 * 凡是添加了 @LogCostTime 注解的方法，都可以打印方法耗时时间
 *
 * @author 🇨🇳中国印🇨🇳 zyexplorej2ee@sina.com
 * @since 2022年01月17日 21:40:46
 * @since 1.0.0
 */
@Component
@Aspect
@Slf4j
public class TimeCostAspect {

    /**
     * 方法说明：定义切入点：匹配所有标注了 @LogCostTime 的方法
     *
     * @param joinPoint 切入点
     * @author ZhuYin
     * @since 2024年12月26日
     */
    @Around("@annotation(com.passion.annotation.LogCostTime)")
    public Object logCostTimeForAnnotatedMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        return logCostTime(joinPoint);
    }


    /**
     * 方法说明：定义切入点：匹配 com.passion.modules 包及其子包下的所有方法
     *
     * @param joinPoint 切入点
     * @author ZhuYin
     * @since 2024年12月26日
     */
    @Around("execution(* com.passion.modules.*..*(..)) || execution(* com.passion.common.*..*(..))")
    public Object logCostTimeForPackageMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        return logCostTime(joinPoint);
    }


    /**
     * 方法说明：统计方法耗时的通用逻辑
     *
     * @param joinPoint 切入点
     * @author ZhuYin
     * @since 2024年12月26日
     */
    private Object logCostTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long elapsedTime = System.currentTimeMillis() - start;
            String methodName = joinPoint.getSignature().getName();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            String logMessage = String.format("Method: %s.%s ==> CostTime: %d ms", className, methodName, elapsedTime);
            log.info(logMessage);
        }
    }

}